package com.emm.yixun.website.filter;

import java.lang.reflect.Method;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.handler.HandlerInterceptorAdapter;

import com.emm.yixun.anotations.AvoidDuplicateSubmission;
import com.emm.yixun.common.model.User;
import com.emm.yixun.website.common.utils.security.ShiroUtil;
import com.emm.yixun.website.utils.TokenProcessor;

/**
 * @Title:
 * @Description: 防止重复提交过滤器
 * @Author:Administrator
 * @Since:2017年4月24日
 * @Version:1.1.0
 */
public class AvoidDuplicateSubmissionInterceptor extends HandlerInterceptorAdapter {

	@Override
	public boolean preHandle(HttpServletRequest request,HttpServletResponse response, Object handler) throws Exception {
		
		User user = ShiroUtil.getCurrentUser();
		if(user!=null){
			if(handler instanceof org.springframework.web.servlet.resource.DefaultServletHttpRequestHandler){
				return true;
			}
			HandlerMethod handlerMethod = (HandlerMethod) handler;
			Method method = handlerMethod.getMethod();

			AvoidDuplicateSubmission annotation = method.getAnnotation(AvoidDuplicateSubmission.class);
			if (annotation != null) {
				boolean needSaveSession = annotation.needSaveToken();
				if (needSaveSession) {
					request.getSession(false).setAttribute("token",TokenProcessor.getInstance().generateToken(request));
				}
				boolean needRemoveSession = annotation.needRemoveToken();
				if (needRemoveSession) {
					 if (isRepeatSubmit(request)) {
						 return false;
					 }
					 request.getSession(false).removeAttribute("token");
				}
			}
			return true;
		}
		return true;
	}

	private boolean isRepeatSubmit(HttpServletRequest request) {
		String serverToken = (String) request.getSession(false).getAttribute("token");
		if (serverToken == null) {
			return true;
		}
		String clinetToken = request.getParameter("token");
		if (clinetToken == null) {
			return true;
		}
		if (!serverToken.equals(clinetToken)) {
			return true;
		}
		return false;
	}
	
}
